﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;

using SynergyControls;
using SynergyLib.DSP;
using SharpDX.XAudio2;

namespace XAudio2Controls
{
    public class FlangerPanel : EffectsPanel, IEffectParams
    {
        #region Properties
        private float MaxDelayInSeconds
        {
            get { return 0.014f; }
        }

        /// <summary>
        /// Max feedback level in percent form.  
        /// 1.0 = 100%, 
        /// 0.56 = 56%, 
        /// etc
        /// </summary>

        private float MaxOscillatorRateInHz
        {
            get { return 5.0f; }
        }       
        public float DelayMS
        {            
            get 
            { 
                return DialAngle1 / 360 * MaxDelayInSeconds;
            }            
        }
        public float Feedback
        {
            get 
            { 
                return DialAngle2 / 360; 
            }
        }
        public float Rate
        {
            get
            {
                float rate = DialAngle3 / 360 * MaxOscillatorRateInHz;
                //string formattedRate = (Math.Round(rate, 2)).ToString() + "Hz";
                //ParamLabel3Content = formattedRate;
                return rate;
            }
        }
        public FlangerEffect flange { get; set; }
        #endregion Properties

        /// <summary>
        /// Static FlangerPanel constructor for a custom control
        /// </summary>
        static FlangerPanel()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(FlangerPanel), new FrameworkPropertyMetadata(typeof(EffectsPanel)));
        }
        /// <summary>
        /// Construct an instance of a FlangerPanel control with respect to a given SubmixVoice.
        /// </summary>
        /// <param name="submixer"></param>
        public FlangerPanel(SubmixVoice submixer, Collection<EffectDescriptor> fxChainReference)
        {
            FxChain = fxChainReference;
            EffectParams = this;
            effectType = EffectTypes.Flanger;
            Submixer = submixer;            
            this.Effect = new FlangerEffect();
            flange = (FlangerEffect)Effect;
            this.effectDescriptor = new EffectDescriptor(Effect);
        }

        protected override void UpdateParameters()
        {            
            if (ParameterEnabled)
            {               
                FlangerParams prms = new FlangerParams()
                {
                    DelayMS = this.Param1,
                    Feedback = this.Param2,
                    Rate = this.Param3,
                };
                flange.Parameters = prms;
            }
        }

        #region IEffectParams
        public float Param1
        { 
            get
            {
                ParamLabel1Content = GetParam1Readout();
                return DelayMS;
            } 
        }
        public float Param2
        {
            get
            {
                ParamLabel2Content = GetParam2Readout();
                return Feedback;
            }
        }
        public float Param3
        {
            get
            {
                ParamLabel3Content = GetParam3Readout();
                return Rate;
            }
        }
        public float Param4
        {
            get;
            set;
        }

        public string ParamName1
        {
            get
            {
                return "Delay";
            }
        }
        public string ParamName2
        {
            get 
            {
                return "Feedback";
            }
        }
        public string ParamName3
        {
            get
            {
                return "Rate";
            }
        }
        public string ParamName4
        {
            get
            {
                return GetParam4Readout();
            }
        }

        public string GetParam1Readout()
        {
            return ((Math.Round(DelayMS, 4)) * 1000).ToString() + "ms";
        }
        public string GetParam2Readout()
        {
            return (Math.Round(Feedback, 3) * 100).ToString() + "%";
        }
        public string GetParam3Readout()
        {
            return (Math.Round(Rate, 2)).ToString() + "Hz";
        }
        public string GetParam4Readout()
        {
            return null;
        }
        #endregion IEffectParams
    }
}
